/*
 * OpenStreetMap Notes:
 *   Tiles are 256 x 256 pixel PNG files
 *   Each zoom level is a directory, each column is a subdirectory,
 *     and each tile in that column is a file
 *   Filename(url) format is /zoom/x/y.png
 *
 *
 * Servers:
 *   OSM Mapnick -- http://[abc].tile.openstreetmap.org/zoom/x/y.png
 *     Where abc are seperate subdomains to get around browser limitations and number of simultaneous
 *     HTTP connections to each host
 *
 * X/Y Coordinates:
 *   X goes from 0 (left edge is 180 W) to 2 ^ zoom - 1 (right edge is 180 E)
 *   Y goes from 0 (top edge is 85.0511 N) to 2 ^ zoom - 1 (bottom edge is 85.0511 S)
 *
 * Projection to tile names:
 *   X = longitude
 *   Y = log( tan( lat ) + sec( lat ) ) --> lat/lon are in radians
 *
 *  Need to transform range of x and y to 0-1 and shft origin to top left corner
 *   x = ( 1 + ( X / pi )) / 2
 *   y = ( 1 - ( Y / pi )) / 2
 *
 *   n = 2 ^ zoom
 *
 *   tilex = x * n
 *   tiley = y * n
 */

#ifndef MAPGRAB_H
#define MAPGRAB_H

#include <QtCore/QtCore>
#include <QtGui/QtGui>
#include <QtNetwork/QtNetwork>
#include <math.h>
#include <iostream>

using namespace std;

#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif

#ifndef M_ZOOMLEVELS
#define M_ZOOMLEVELS
#define M_Z0 156.412 * 1000
#define M_Z1 78.206 * 1000
#define M_Z2 39.103 * 1000
#define M_Z3 19.551 * 1000
#define M_Z4 9.776 * 1000
#define M_Z5 4.888 * 1000
#define M_Z6 2.444 * 1000
#define M_Z7 1.222 * 1000
#define M_Z8 610984
#define M_Z9 305492
#define M_Z10 152746
#define M_Z11 76373
#define M_Z12 156.412
#define M_Z13 78.206
#define M_Z14 39.103
#define M_Z15 19.551
#define M_Z16 9.776
#define M_Z17 4.888
#endif

// S = C * cos( lat ) / 2 ^ ( zoom + 8 ) -> 2 ^ ( zoom + 8 ) = C * cos( lat ) / S -> zoom + 8 = log ( C * cos ( lat ) / S ) / log( 2 ) -> zoom = log ( C * cos ( lat ) / S ) / log( 2 ) - 8
// C -> Earth circuference 40,075.16
// Open street map tile image is 256x256 PNG
const int tdim = 256;

class MapGrab : public QObject {

    Q_OBJECT

public:
    int width;
    int height;
    int zoom;
    qreal latitude;
    qreal longitude;

    MapGrab( QObject *parent=0 );

    QNetworkDiskCache *cache;

    void invalidate();
    void pan();
    void render(QPainter *p, const QRect &rect, const bool &resizeFlag);
    int zoomCalculation(qreal lat, qreal dist);

private slots:
    void handleNetworkData( QNetworkReply *reply );
    void download();

signals:
    void updated( const QRect &rect);

protected:
    QRect tileRect( const QPoint &tp);

private:
    QPointF coord2tile(qreal lat, qreal lon, int zoom);
    QPointF tile2coord(qreal tileX, qreal tileY, int zoom);
    uint qHash( const QPoint& p );

    QPoint m_offset;
    QPainter *locPaint;
    QRect m_tilesRect;
    QPixmap m_emptyTile;
    QPixmap m_currentLevel;
    QHash<QPoint, QPixmap> m_tilePixmaps;
    QNetworkAccessManager m_manager;
    QUrl m_url;
};

/*class MapGrab : public QWidget {

    Q_OBJECT;

public:
    MapGrab( QWidget *parent=0 );
    void setCenter( qreal lat, qreal lng);

public slots:
    void toggleNightMode();

protected:
    void activateZoom();
    void resizeEvent(QResizeEvent *);
    void paintEvent(QPaintEvent *event);
    void timerEvent(QTimerEvent *);

private:
    SlippyMap *m_normalMap;
    SlippyMap *m_largeMap;
    bool pressed;
    bool snapped;
    QPoint pressPos;
    QPoint dragPos;
    QBasicTimer tapTimer;
    bool zoomed;
    QPixmap zoomPixmap;
    QPixmap maskPixmap;
    bool invert;
};*/



#endif // MAPGRAB_H
